package com.xxmw.transaction.service.app.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxmw.transaction.common.excep.service.TransactionException;
import com.xxmw.transaction.common.utils.AESHelper;
import com.xxmw.transaction.common.utils.Assert;
import com.xxmw.transaction.common.utils.Md5Util;
import com.xxmw.transaction.common.utils.keygen.IdGenerator;
import com.xxmw.transaction.common.utils.keygen.Sequence;
import com.xxmw.transaction.mapper.app.VipRecordMapper;
import com.xxmw.transaction.model.app.User;
import com.xxmw.transaction.model.app.VipPrice;
import com.xxmw.transaction.model.app.VipRecord;
import com.xxmw.transaction.service.app.IVipRecordService;
import com.xxmw.transaction.service.app.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.HashMap;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yamoo
 * @since 2020-07-06
 */
@Service
@Slf4j
public class VipRecordServiceImpl extends ServiceImpl<VipRecordMapper, VipRecord> implements IVipRecordService {

    @Autowired
    private UserService userService;

    @Autowired
    private RestTemplate  restTemplate;

    @Value("${bitWorld.baseURL}")
    private String BITWORLD_BASE_URL;

    @Value("${bitWorld.submitOrder}")
    private String BITWORLD_ORDER_PATH;

    @Value("${bitWorld.accessKey}")
    private String BITWORLD_ACCESSKEY;

    @Value("${bitWorld.key}")
    private String KEY;

    private final String USDT = "USDT";


    @Override
    public HashMap<String, Object> createOrder(String username, VipPrice price) {
        HashMap<String, Object> result = new HashMap<>();
        User user = userService.getUser(username);
        if(Assert.isNullOrEmpty(user)){
            throw new TransactionException("用户不存在");
        }

        // 创建订单实体类
        VipRecord record = getOrderModel(user, price);

        // 调用bitWorld 获取充值码
        String url = sendOrderToBitWorld(record);
        // 存储数据
        save(record);
        result.put("orderId", record.getOrderId());
        result.put("url", url);
        return result;
    }

    @Override
    public void orderSuccess(String orderId) {
        Integer oldStatus = VipRecord.Status.UNFINISHED.getValue();
        Integer newStatus = VipRecord.Status.FINISHED.getValue();
        int i = baseMapper.updateStatusById(orderId, oldStatus, newStatus);
        if (i > 0) {
            // 更新成功逻辑
            VipRecord record = getById(orderId);
            if(Assert.isNullOrEmpty(record)) {
                log.error("bitWorld回调订单不存在，订单号：{}", orderId);
                return;
            }
            // 增加VIP时间
            userService.addVipTime(record.getUsername(), record.getMonth() * 30);
            log.info("用户{}续费VIP,VIP续费时长：{}天",record.getUsername(), record.getMonth()*30);
        } else {
            log.error("收到重复回调，订单号：{}", orderId);
        }
    }

    /**
     * 获取订单实体类
     * @param user 用户实体类
     * @param price 价格实体类
     * @return 订单实体对象
     */
    private VipRecord getOrderModel (User user, VipPrice price) {

        VipRecord record = new VipRecord();
        // 生成id
        IdGenerator idGenerator = Sequence.getInstance();
        String id = "TS"+idGenerator.generate().toString();

        record.setOrderId(id);
        record.setUserId(user.getId());
        record.setUsername(user.getUsername());
        record.setMonth(price.getMonthCount());
        record.setQuantity(price.getPrice());
        record.setStatus(VipRecord.Status.UNFINISHED.getValue());
        record.setCreateTime(new Date());
        record.setCreateUser(user.getUsername());
        return record;
    }

    /**
     * bitWorld 下单
     * @param record 订单实体类
     */
    private String sendOrderToBitWorld (VipRecord record) {
        // 获取参数列表
        JSONObject params = getOrderParams(record);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> request = new HttpEntity<>(params.toJSONString(), headers);
        // 发起请求
        String resp = restTemplate.postForObject(BITWORLD_BASE_URL + BITWORLD_ORDER_PATH, request, String.class);
        log.info("bitWorld下单返回信息：{}", resp);

        // 结果处理
        JSONObject result = JSONObject.parseObject(resp);
        String url = result.getString("result");
        if (Assert.isNullOrEmpty(url)) {
            log.error("bitworld充值异常：{}", result);
            throw new TransactionException("当前充值人数过多，请稍后再试");
        }
        return url;
    }

    /**
     * 获取传参列表
     * @param record 订单实体类
     * @return 参数列表
     */
    private JSONObject getOrderParams (VipRecord record) {
        JSONObject params = new JSONObject();
        params.put("accessKey", BITWORLD_ACCESSKEY);
        params.put("orderNo", record.getOrderId());
        // params.put("valuationCurrency", USDT);
        // params.put("valuationQuantity", record.getQuantity());
        params.put("receivableQuantity", record.getQuantity());
        params.put("receivableCurrency", USDT);
        // 获取随机码
        params.put("randomStr", String.valueOf(System.currentTimeMillis()));
        // 获取签名参数
        params.put("signInfo", sign(params, record));
        return params;
    }


    /**
     * 获取签名
     * @param params 待签名参数
     * @param record 记录实体类
     */
    private String sign (JSONObject params, VipRecord record) {
       return sign(BITWORLD_ACCESSKEY, record.getOrderId(),params.getString("randomStr"), KEY);
    }

    /**
     * 获取签名
     * @param accessKey id
     * @param orderNo 订单号
     * @param randomStr 随机串
     * @return
     */
    private String sign(String accessKey, String orderNo, String randomStr, String aesKey) {
        // accessKey + orderNo + randomStr
        String data = accessKey + orderNo + randomStr;
        String sign;
        try {
            sign = AESHelper.aesEncryptString(data, aesKey, AESHelper.IV_STRING_16);
        } catch (Exception e) {
            throw new TransactionException("获取签名数据失败");
        }
        log.info("bitWolrd签名为: {}", sign);
        sign = Md5Util.encoder(sign).substring(2, 30);
        log.info("bitWolrd签名截取后为: {}", sign);
        return sign;
    }

    /**
     * 校验签名
     * @param orderNo
     * @param randomStr
     * @return
     * @throws Exception
     */
    @Override
    public boolean verifySign(String signInfo, String orderNo,String randomStr) {
        return sign(BITWORLD_ACCESSKEY, orderNo, randomStr, KEY).equals(signInfo);
}

}
